<!DOCTYPE html>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../../resources/run-after-layout-and-paint.js"></script>
<style>
#box {
    position: absolute;
    left: 0;
    top: 0;
    width: 100px;
    height: 100px;
    background: green;
    box-shadow: 1.4px 1.4px blue;
}
</style>
<div id="box"></div>
<script>
var t = async_test('Tests whether a repaint rect encompasses box-shadow with subpixel offset when the shadow changes.');

// Accepts [x, y, width, height] rects. Checks if the first argument contains the second.
function rectContainsRect(outer, inner) {
    return outer[0] <= inner[0]
        && outer[1] <= inner[1]
        && outer[0] + outer[2] >= inner[0] + inner[2]
        && outer[1] + outer[3] >= inner[1] + inner[3];
}

t.step(function() {
    assert_true(!!window.internals, 'Test requires window.internals.');
});

var box = document.getElementById('box');
runAfterLayoutAndPaint(function() {
    if (window.internals)
        internals.startTrackingRepaints(document);
    box.style.boxShadow = 'none';

    runAfterLayoutAndPaint(function() {
        t.step(function() {
            if (!window.internals)
                return;
            var layers_dump = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_DETAILED_INVALIDATIONS);
            var layers = JSON.parse(layers_dump).layers;
            var scrollingContentsLayer = layers[0];
            var invalidations = scrollingContentsLayer.invalidations;
            var shadowRect = [1.4, 1.4, 100, 100];
            assert_true(invalidations.some(paintInvalidation => rectContainsRect(paintInvalidation.rect, shadowRect)),
                        'Subpixel shadow ' + JSON.stringify(shadowRect) + ' should be repainted. ' + layers_dump);
            internals.stopTrackingRepaints(document);
        });
        t.done();
    });
});
</script>
